#include <cassert>
#include "miniutil/storageservice.h"

using namespace miniutil::frame;

int server_function()
{
	miniutil::frame::StorageService stor_service;
	stor_service.SetLocalRoot("f:/test");
	stor_service.SetMode(StorageService::MODE_SERVER, 1112);
	stor_service.Start();
	while(true)
	{
		miniutil::thread::sleep(1000);
	}
}

int client_function()
{
	int ret;
	char buf[100];
	char readbuf[100];
	memset(buf, 0x31, sizeof(buf));

	miniutil::frame::StorageService stor_service;
	stor_service.SetLocalRoot("f:/test");
	stor_service.SetMode(StorageService::MODE_REMOTE_CLIENT);
	stor_service.Start();

	std::string filename = "a/remote.txt@192.168.1.173:1112";
	ret = stor_service.Write(filename, (char*)buf, 100,  100);
	ret = stor_service.Write(filename, (char*)buf, 500,  100);
	ret = stor_service.Write(filename, (char*)buf, 450,  100);
	ret = stor_service.Read(filename, (char*)readbuf, 100, 100);
	if(ret != 100)
		std::cout<<"Read Error"<<std::endl;
	else
	{
		std::cout<<"Read 100 Bytes"<<std::endl;
		assert(!memcmp(buf, readbuf, 100));
	}

	ret = stor_service.Read(filename, (char*)readbuf, 1, 100);
	assert(ret == -1);

	std::list<std::pair<fs_t, fs_t> > einfo;
	ret = stor_service.ExistInfo(filename, einfo);

	std::list<std::pair<fs_t, fs_t> >::iterator iter_lpff;
	for(iter_lpff = einfo.begin(); iter_lpff != einfo.end(); iter_lpff ++)
	{
		std::cout<<iter_lpff->first<<":"<<iter_lpff->second<<std::endl;
	}

	stor_service.Stop();
	return 0;
}

int client_function_2()
{
	miniutil::frame::StorageService stor_service;
	stor_service.SetLocalRoot("f:/test");
	stor_service.SetMode(StorageService::MODE_REMOTE_CLIENT);
	std::string filename = "a/remote.txt@192.168.1.173:1112";
	FILE* pfile = fopen("e:/movie/ganen.flv", "rb");
	if(pfile == NULL)
	{
		std::cout<<"Can not open file"<<std::endl;
		return -1;
	}
	stor_service.Start();

	fseek(pfile, 0, SEEK_END);
	int len = ftell(pfile);
	fseek(pfile, 0, SEEK_SET);
	char buf[1000000];
	int havewrite = 0;
	while(!feof(pfile))
	{
		int readlen = fread(buf, 1, sizeof(buf), pfile);
		stor_service.Write(filename, buf, havewrite, readlen);
		havewrite += readlen;
	}

	stor_service.Stop();
	return 0;
}

int test_function()
{
	miniutil::frame::StorageService stor_service;
	//stor_service.Start();
	int ret;
	char readbuf[1000];
	stor_service.SetLocalRoot("f:/test");
	std::string filename = "/a/b.txt";
	//ret = stor_service.Read(filename, (char*)readbuf, 100, 100);
	//should create directory
	//should not create file
	//should return -1;

	int totallen = 36458455;
	int piecelen = 256*1024;
	int startidx = -10;

	char* buf = new char[piecelen];
	memset(buf, 0xFF, piecelen);

	int piecenum = totallen/piecelen +1;
	int startpos;
	if(startidx < 10)
		startpos = piecenum-10;
	else
		startpos = piecenum;

	if(startpos > piecenum-1)
		startpos = piecenum - 1;
	if(startpos < 0)
		startpos = 0;

	ret = stor_service.SetLength(filename, totallen);
	for(int i=0; i< piecenum; i++)
	{
		int piecetowrite = (startpos+i)%piecenum;
		int lentowrite = piecelen;
		if(piecetowrite +1 == piecenum)
			lentowrite = totallen%piecelen;
		if(i + 1== piecenum)
			stor_service.Write(filename, (char*)buf, piecetowrite*piecelen, lentowrite);
		else
			stor_service.Write(filename, (char*)buf, piecetowrite*piecelen, lentowrite);
	}

	//ret = stor_service.Write(filename, (char*)buf, 100,  100);
	//ret = stor_service.Read(filename, (char*)readbuf, 100, 100);
	//ret = stor_service.Read(filename, (char*)readbuf, 100, 150);

	std::list<std::pair<fs_t, fs_t> > info;
	stor_service.ExistInfo(filename, info);
	//ret = stor_service.Write(filename, (char*)buf, 0,  100);
	
	//ret = stor_service.Remove(filename);

	//stor_service.Stop();
	delete []buf;
	return 0;
}

int main(int argc, char** argv)
{
#if 0
{WSADATA data; WSAStartup(MAKEWORD(2,2), &data);}
	int mode = 0;
	if(argc > 2)
		mode = atoi(argv[1]);
	
	if(mode == 0) //client
	{
		//client_function();
		client_function_2();
	}
	else
	{
		server_function();
	}
#else
	test_function();
#endif
	return 0;
}
